package TCP网络编程;

import org.junit.Test;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 实现TCP的网络编程
 * 例题2：客户端发送文件给服务端，服务端将文件保存在本地。
 *
 * @author subei
 * @create 2020-05-16 17:05
 */
public class 客户端发送文件给服务端并保存到本地 {
    //客户端
    @Test
    public void client() throws IOException {
        //1.创建Socket对象，指明服务器端的ip和端口号
        Socket socket = new Socket(InetAddress.getByName("localhost"), 8811);
        //2.获取输出流
        OutputStream ipo = socket.getOutputStream();
        //创建一个输入流，且输入一张图片
        FileInputStream fips = new FileInputStream("自拍.jpeg");
//        FileInputStream fips=new FileInputStream(new File("自拍.jpeg"));
        //3.输出数据
        byte[] bytes = new byte[1024];
        int len;
        while ((len = fips.read(bytes)) != -1) {
            ipo.write(bytes, 0, len);
        }
        //4.关闭资源
        fips.close();
        ipo.close();
        socket.close();


    }

    //服务端
    @Test
    public void server() throws IOException {
        //1.创建服务器端口
        ServerSocket ss = new ServerSocket(8811);
        //2.利用accept接收相应端口传输的数据
        Socket kh1 = ss.accept();
        //3.获取输入流,通过Socket的getInputStream()方获取
        InputStream is = kh1.getInputStream();
        //4.指定输出流
        FileOutputStream fos = new FileOutputStream("自拍3.jpeg");
        //5.读入数据
        byte[] bytes = new byte[1024];
        int len;
        while ((len = is.read(bytes)) != -1) {
            //6.读出数据，保存到本地
            fos.write(bytes, 0, len);
        }

        //6.关闭资源
        fos.close();
        is.close();
        kh1.close();
        ss.close();

    }

    //服务端2
    @Test
    public void serviceClient() {
        ServerSocket ss = null;//就是客户端需要连接的端口号
        Socket ssoc = null;
        InputStream ips = null;
        ByteArrayOutputStream baos = null;

        try {
            //1.创建服务器端的ServerSocket，指明自己的端口号
            ss = new ServerSocket(8806);

            //2.调用accept()表示接收来自于客户端的socket
            ssoc = ss.accept();
            //3.获取输入流,通过Socket的getInputStream()方获取
            ips = ssoc.getInputStream();

            //4.读取输入流中的数据，创建字节数组输出流来接收数据
            baos = new ByteArrayOutputStream();
            byte[] bytes = new byte[5];//创建一个长度为5的字节数组，接收数据
            int len;//每次读取数据的长度
            while ((len = ips.read(bytes)) != -1) {//判断是否读完，读完返回-1
                baos.write(bytes, 0, len);//向字节数组输出流，写入数据
            }
            System.out.println(baos.toString());//输出字节数组输出流中的字符数据

            System.out.println("收到了来自于：" + ssoc.getInetAddress().getHostAddress() + "的数据");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5.关闭资源
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (ips != null) {
                try {
                    ips.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (ssoc != null) {

                try {
                    ssoc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (ss != null) {

                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}
